package com.wst.system.server.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wst.system.config.exception.GlobalExcetion;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wst.system.security.config.AppJWTConfig;
import com.wst.system.security.entity.SelfUserEntity;
import com.wst.system.server.entity.SysOpenApi;
import com.wst.system.server.entity.SysOpenPermission;
import com.wst.system.server.entity.SysOpenToken;
import com.wst.system.server.entity.vo.AppLoginVo;
import com.wst.system.server.entity.vo.PageSearchVo;
import com.wst.system.server.service.SysOpenApiService;
import com.wst.system.server.service.SysOpenPermissionService;
import com.wst.system.server.service.SysOpenTokenService;
import com.wst.system.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wst.system.server.entity.SysOpenApp;
import com.wst.system.server.mapper.SysOpenAppMapper;
import com.wst.system.server.service.SysOpenAppService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;
import com.wst.system.server.entity.vo.SysOpenAppVo;

import javax.crypto.SecretKey;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author X.I.O
 * @since 2025-01-16
 */
@Service
@Transactional
public class SysOpenAppServiceImpl extends ServiceImpl<SysOpenAppMapper, SysOpenApp> implements SysOpenAppService {



    @Override
    public SysOpenApp getById(Serializable id){
        return super.getById(id);
    }


    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }


    @Override
    public boolean updateById(SysOpenApp sysopenapp) {
        return super.updateById(sysopenapp);
    }


    public SysOpenApp updateSysOpenAppById(SysOpenApp sysopenapp) throws GlobalExcetion{
        super.updateById(sysopenapp);
        return sysopenapp;
    }


    public SysOpenApp saveOrUpdateSysOpenApp(SysOpenAppVo sysopenappVo) throws GlobalExcetion{
        SelfUserEntity info=SecurityUtil.getUserInfo();
        SysOpenApp sysopenapp=new SysOpenApp();
        BeanUtils.copyProperties(sysopenappVo,sysopenapp);
        if(sysopenappVo.getId()!=null){
            SysOpenApp sysopenappEntity=super.baseMapper.selectById(sysopenappVo.getId());
            if(sysopenappEntity==null){
                throw new GlobalExcetion(1,"数据不存在");
            }
            super.baseMapper.updateById(sysopenapp);
        }else{
            SysOpenApp app=this.getSysOpenAppByAppName(sysopenappVo.getAppname());
            if(app!=null){
                throw new GlobalExcetion(1,"存在同名app,请改名后重试");
            }
            Boolean createSecretKey=true;
            while (createSecretKey){
                SecretKey secretKey=TextEncryptUtils.generateAesKey();
                String keyStr=TextEncryptUtils.keyToString(secretKey);
                SysOpenApp openApp=this.getSysOpenAppBySecretKey(keyStr);
                if(openApp==null){
                    createSecretKey=false;
                    String secret=TextEncryptUtils.encryptText(sysopenappVo.getAppname(),secretKey);
                    String password=new BCryptPasswordEncoder().encode(secret);
                    sysopenapp.setSecretkey(keyStr);
                    sysopenapp.setPrivatekey(password);
                }
            }
            sysopenapp.setCreateUid(info.getUserId().toString());
            super.baseMapper.insert(sysopenapp);
        }
        return sysopenapp;
    }

    public IPage<SysOpenApp> page(PageSearchVo vo) throws GlobalExcetion{
        LambdaQueryWrapper<SysOpenApp> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(JSONUtil.isNotBlank(vo.getSearch(),"appname")){
            lambdaQueryWrapper.like(SysOpenApp::getAppname,vo.getString("appname"));
        }
        lambdaQueryWrapper.orderByDesc(SysOpenApp::getCreateTime);
        IPage<SysOpenApp> iPage=super.baseMapper.selectPage(new Page(vo.getPageNum(), vo.getPageSize()),lambdaQueryWrapper);
        return iPage;
    }

    @Override
    public SysOpenApp getSysOpenAppByAppName(String appName) throws GlobalExcetion {
        LambdaQueryWrapper<SysOpenApp> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysOpenApp::getAppname,appName);
        return super.baseMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public SysOpenApp getSysOpenAppBySecretKey(String secretKey) throws GlobalExcetion {
        LambdaQueryWrapper<SysOpenApp> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysOpenApp::getSecretkey,secretKey);
        return super.baseMapper.selectOne(lambdaQueryWrapper);
    }

    @Autowired
    private SysOpenTokenService sysOpenTokenService;

    @Override
    public JSONObject login(AppLoginVo vo) throws GlobalExcetion {
        SysOpenApp app=getSysOpenAppBySecretKey(vo.getSecrekey());
        if(app==null){
            throw new GlobalExcetion(1,"app不存在或秘钥错误");
        }
        if(!app.getPrivatekey().equals(vo.getPrivatekey())){
            throw new GlobalExcetion(1,"app不存在或秘钥错误");
        }
        SysOpenPermissionService sysOpenPermissionService= SpringContextUtils.getBean(SysOpenPermissionService.class);
        List<SysOpenPermission> permissionList=sysOpenPermissionService.getSysOpenPermissionListByAppId(String.valueOf(app.getId()));
        if(permissionList!=null && permissionList.size()>0){
            List<String> ids=permissionList.stream().map(SysOpenPermission::getApiId).collect(Collectors.toList());
            SysOpenApiService service=SpringContextUtils.getBean(SysOpenApiService.class);
            List<SysOpenApi> sysOpenApis=service.getSysOpenApiListByApiIdList(ids);
            if(sysOpenApis!=null && sysOpenApis.size()>0){
                List<String> urls=sysOpenApis.stream().map(SysOpenApi::getApiUrl).collect(Collectors.toList());
                app.setUrl(urls);
            }
        }
        String token=JWTTokenUtil.createAppToken(app);
        SysOpenToken sysOpenToken=new SysOpenToken();
        sysOpenToken.setAppname(app.getAppname());
        sysOpenToken.setApptoken(AppJWTConfig.tokenPrefix+token);
        sysOpenTokenService.saveSysOpenToken(sysOpenToken);
        JSONObject jsonObject=new JSONObject();
        jsonObject.put(AppJWTConfig.tokenHeader,AppJWTConfig.tokenPrefix+token);
        return jsonObject;
    }


}